<?php

namespace App\Admin\Console\Commands;

use App\Admin\Models\AdminPermission;
use App\Admin\Models\AdminRole;
use App\Admin\Models\AdminUser;
use App\Admin\Models\Config;
use App\Admin\Models\ConfigCategory;
use App\Admin\Models\VueRouter;
use App\Admin\Models\SystemModel;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Artisan;

class AdminInitCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = '
        admin:init
        {--force : 强制覆盖}
    ';
    
    

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '初始化基础路由配置，超级管理员角色和权限';

    public static $initConfirmTip = '初始化操作，会清空路由、系统配置、管理员、角色和权限表，以及相关关联表数据。是否确认？';

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        if (config()->get('app.env')=='production') {
            $this->warn('生产环境下不适用');
            return false;
        }
        if (!$this->option('force') && !$this->confirm(static::$initConfirmTip)) {
            return false;
        }
        $this->createDemoResource();// 创建系统模型对应的资源
        DB::beginTransaction();
        try {
            $this->createVueRouters();// 创建基础菜单
            $this->createSystemModels();// 创建系统模型
            $this->createUserRolePermission();// 创建用户角色权限
            $this->createDefaultConfigs();// 创建默认配置
            $this->info('初始化完成，管理员为：admin，密码为：000000');
            DB::commit();
            return true;
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            $this->error($e->getMessage());
            return false;
        }
    }

    /**
     * 创建基础菜单
     */
    protected function createVueRouters()
    {
        $inserts = [
            [1, 0, '首页', 'index', 0, 'dashboard', 1, null],

            [2, 0, '路由配置', null, 1, 'tree-table', 1, 'pass-get-vue-routers'],
            [3, 2, '所有路由', 'vue-routers', 0, null, 1, 'pass-get-vue-routers'],
            [4, 2, '添加路由', 'vue-routers/create', 1, null, 1, 'pass-post-vue-routers'],
            [5, 2, '编辑路由', 'vue-routers/:id(\\d+)/edit', 2, null, 0, 'pass-put-vue-routers'],

            [6, 0, '管理员管理', null, 2, 'user', 1, 'pass-get-admin-users'],
            [7, 6, '管理员列表', 'admin-users', 0, null, 1, 'pass-get-admin-users'],
            [8, 6, '添加管理员', 'admin-users/create', 1, null, 1, 'pass-post-admin-users'],
            [9, 6, '编辑管理员', 'admin-users/:id(\\d+)/edit', 2, null, 0, 'pass-put-admin-users'],
            [10, 6, '管理员详情', 'admin-users/:id(\d+)', 3, null, 0, 'pass-get-admin-users'],

            [11, 0, '角色管理', null, 3, 'peoples', 1, 'pass-get-admin-roles'],
            [12, 11, '角色列表', 'admin-roles', 0, null, 1, 'pass-get-admin-roles'],
            [13, 11, '添加角色', 'admin-roles/create', 1, null, 1, 'pass-post-admin-roles'],
            [14, 11, '编辑角色', 'admin-roles/:id(\\d+)/edit', 2, null, 0, 'pass-put-admin-roles'],
            [15, 11, '角色详情', 'admin-roles/:id(\\d+)', 3, null, 0, 'pass-get-admin-roles'],

            [16, 0, '权限管理', null, 4, 'captcha', 1, 'pass-get-admin-permissions'],
            [17, 16, '权限列表', 'admin-permissions', 0, null, 1, 'pass-get-admin-permissions'],
            [18, 16, '添加权限', 'admin-permissions/create', 1, null, 1, 'pass-post-admin-permissions'],
            [19, 16, '编辑权限', 'admin-permissions/:id(\\d+)/edit', 2, null, 0, 'pass-put-admin-permissions'],
            [20, 16, '权限详情', 'admin-permissions/:id(\\d+)', 3, null, 0, 'pass-get-admin-permissions'],

            [21, 0, '配置管理', null, 5, 'cog-fill', 1, 'pass-get-configs'],
            [22, 21, '配置分类', 'config-categories', 0, null, 1, 'pass-all'],
            [23, 21, '所有配置', 'configs', 1, null, 1, 'pass-get-configs'],
            [24, 21, '添加配置', 'configs/create', 2, null, 1, 'pass-post-configs'],
            [25, 21, '编辑配置', 'configs/:id(\\d+)/edit', 3, null, 0, 'pass-put-configs'],
            [26, 21, '配置详情', 'configs/:id(\\d+)', 4, null, 0, 'pass-get-configs'],
            [27, 21, '系统设置', '/configs/system_basic', 5, 'cog-fill', 1, 'pass-all'],
            [28, 21, '示例设置', '/configs/demo_config', 6, 'cog-fill', 1, 'pass-all'],

            [29, 0, '模型管理', null, 6, 'tree', 1, 'pass-get-system-models'],
            [30, 29, '模型配置', 'system-models', 0, null, 1, 'pass-get-system-models'],
            [31, 29, '模型字段', 'system-models/:id(\d+)', 1, null, 0, 'pass-get-system-models'],
            [32, 29, '编辑模型', 'system-models/:id(\d+)/edit', 2, null, 0, 'pass-put-system-models'], 

            [33, 0, '文件管理', 'system-media', 7, 'documentation', 1, 'pass-get-$s'],

            [34, 0, 'API文档', 'api-documents', 8, 'single-file', 1, 'pass-get-api-documents'],

            [35, 0, '操作日志', 'admin-operation-logs', 9, 'skill', 1, 'pass-get-operation-logs'],
            [36, 0, '操作日志详情', 'admin-operation-logs/:id(\\d+)', 3, null, 0, 'pass-get-operation-logs'],

            [37, 0, '示例管理', null, 10, null, 1, 'pass-get-demos'],
            [38, 37, '示例列表', 'demos', 0, null, 1, 'pass-get-demos'],
            [39, 37, '添加示例', 'demos/create', 1, null, 1, 'pass-post-demos'],
            [40, 37, '编辑示例', 'demos/:id(\d+)/edit', 2, null, 0, 'pass-put-demos'],
            [41, 37, '示例详情', 'demos/:id(\d+)', 3, null, 0, 'pass-get-demos'],
        ];

        $inserts = $this->combineInserts(
            ['id', 'parent_id', 'title', 'path', 'order', 'icon', 'menu', 'permission'],
            $inserts,
            [
                'cache' => 0,
                'created_at' => now(),
                'updated_at' => now()
            ]
        );

        DB::table('vue_routers')->delete();
        VueRouter::insert($inserts);
        DB::table('vue_admin_user_routers')->delete();
        $this->info("基础菜单创建成功");
    }

    /**
     * 创建系统模型
     */
    protected function createSystemModels()
    {
        foreach (array_merge(array_keys(SystemModel::$systemModels),array_keys(SystemModel::$demoModels)) as $value) {
            Artisan::call("admin:make-model", [
                'slug' => $value,
                '--force' => true,
            ]);
        }
        $this->info("系统模型创建成功");
    }

    /**
     * 创建示例资源
     */
    protected function createDemoResource()
    {
        Artisan::call("admin:make-resource", [
            'slug' => 'demos',
            '--force' => true,
        ]);
        $this->info("示例资源创建成功");
    }

    /**
     * 创建用户角色、权限、路由
     */
    protected function createUserRolePermission()
    {
        DB::table('admin_users')->delete();
        DB::table('admin_roles')->delete();
        DB::table('admin_permissions')->delete();

        collect(['admin_role_permission', 'admin_user_permission', 'admin_user_role', 'vue_router_role'])
            ->each(function ($table) {
                DB::table($table)->delete();
            });

        $user = AdminUser::create([
            'name' => '管理员',
            'username' => 'admin',
            'password' => bcrypt('000000'),
        ]);

        $user->roles()->create([
            'name' => '超级管理员',
            'slug' => 'administrator',
        ]);

        // 创建超级管理员的权限
        AdminRole::first()
            ->permissions()
            ->create(
                [
                    'name' => '所有权限',
                    'slug' => 'pass-all',
                    'http_path' => '*',
                ]
            );
        
        // 创建管理员用户的权限
        AdminPermission::insert([
            [
                'name' => '内部标题权限',
                'slug' => 'pass-getInnerTitle',
                'http_path' => "/getInnerTitle*",
                'http_method' => 'POST',
                'created_at' => '2022-02-22 02:22:22',
            ],
            [
                'name' => '模型字段权限',
                'slug' => 'pass-field',
                'http_path' => "/searchField*\n/formField*\n/listField*\n/detailField*",
                'http_method' => 'GET',
                'created_at' => '2022-02-22 02:22:22',
            ],
            [
                'name' => '数据恢复权限',
                'slug' => 'pass-restore',
                'http_path' => "/restore*",
                'http_method' => 'PUT',
                'created_at' => now(),
            ],
            [
                'name' => '彻底删除权限',
                'slug' => 'pass-force-delete',
                'http_path' => '/forceDelete*',
                'http_method' => 'DELETE',
                'created_at' => now(),
            ]
        ]);
        foreach (array_merge(SystemModel::$systemModels,SystemModel::$demoModels) as $key => $value) {
            if ($value['name']) {
                $this->makeAdminPermission($key, $value['name']);
            }
        }
        $this->info("用户角色权限创建成功");
    }

    /**
     * 创建默认配置
     */
    protected function createDefaultConfigs()
    {
        $categories = [
            [1, '系统设置', 'system_basic'],
            [2, '示例设置', 'demo_config'],
        ];
        $categories = $this->combineInserts(
            ['id', 'name', 'slug'],
            $categories,
            [
                'created_at' => now(),
                'updated_at' => now(),
            ]
        );
        $configs = [
            [1,
                SystemModel::TYPE_INPUT,
                '系统名称',
                'app_name',
                null,
                null,
                '后台',
                'required|max:20'
            ],
            [1,
                SystemModel::TYPE_FILE,
                '系统 LOGO',
                'app_logo',
                null,
                json_encode([
                    'max' => "1",
                    'ext' => "jpg,png,jpeg"
                ],JSON_UNESCAPED_UNICODE),
                null,
                'nullable'
            ],
            [1,
                SystemModel::TYPE_OTHER,
                '首页路由',
                'home_route',
                null,
                null,
                '1',
                'required|exists:vue_routers,id'
            ],
            [1,
                SystemModel::TYPE_INPUT,
                'CDN 域名',
                'cdn_domain',
                null,
                null,
                '/',
                'required'
            ],
            [1,
                SystemModel::TYPE_SINGLE,
                '后台登录验证码',
                'admin_login_captcha',
                null,
                json_encode([
                    'options' => "1=>开启\n0=>关闭",
                    'type' => 'single_box',
                    'sample' => '1',
                ],JSON_UNESCAPED_UNICODE),
                '0',
                'required'
            ],
            [1,
                SystemModel::TYPE_SINGLE,
                '文件存储方式',
                'filesystem_disk',
                '注意：新上传的文件会更改为选择的存储方式，原来的文件会按照之前的方式存储。',
                json_encode([
                    'options' => "uploads=>本地\nqiniu=>七牛云",
                    'type' => 'single_box',
                    'sample' => '1',
                ],JSON_UNESCAPED_UNICODE),
                'uploads',
                'required'
            ],
            [2,
                SystemModel::TYPE_INPUT,
                '文本域',
                'input',
                '文本域',
                null,
                '1',
                null
            ],
            [2,
                SystemModel::TYPE_DYNAMIC_INPUT,
                '动态文本域',
                'dynamic_input',
                '动态文本域',
                null,
                '1',
                null
            ],
            [2,
                SystemModel::TYPE_TEXTAREA,
                '多行文本域',
                'textarea',
                '多行文本域',
                null,
                '1',
                null
            ],
            [2,
                SystemModel::TYPE_DYNAMIC_TEXTAREA,
                '动态多行文本域',
                'dynamic_textarea',
                '动态多行文本域',
                null,
                '1',
                null
            ],
            [2,
                SystemModel::TYPE_FILE,
                '单文件上传',
                'single_file',
                '单文件上传',
                json_encode([
                    'max' => "1",
                    'ext' => null
                ],JSON_UNESCAPED_UNICODE),
                null,
                null
            ],
            [2,
                SystemModel::TYPE_FILE,
                '多文件上传',
                'multiple_file',
                '多文件上传',
                json_encode([
                    'max' => "2",
                    'ext' => null
                ],JSON_UNESCAPED_UNICODE),
                null,
                null
            ],
            [2,
                SystemModel::TYPE_SINGLE,
                '单选框',
                'single_box',
                '单选框',
                json_encode([
                    'options' => "1=>选项1\n2=>选项2",
                    'type' => 'single_box',
                    'sample' => '1',
                ],JSON_UNESCAPED_UNICODE),
                '1',
                null
            ],
            [2,
                SystemModel::TYPE_MULTIPLE,
                '多选框',
                'multiple_box',
                '多选框',
                json_encode([
                    'options' => "1=>选项1\n2=>选项2",
                    'type' => 'multiple_box',
                    'sample' => '1',
                    'format' => 'json',
                ],JSON_UNESCAPED_UNICODE),
                json_encode(["1","2"]),
                null
            ],
            [2,
                SystemModel::TYPE_SINGLE,
                '单选下拉',
                'single_select',
                '单选下拉',
                json_encode([
                    'options' => "1=>选项1\n2=>选项2",
                    'type' => 'single_select',
                    'sample' => '1',
                ],JSON_UNESCAPED_UNICODE),
                '1',
                null
            ],
            [2,
                SystemModel::TYPE_MULTIPLE,
                '多选下拉',
                'multiple_select',
                '多选下拉',
                json_encode([
                    'options' => "1=>选项1\n2=>选项2",
                    'type' => 'multiple_select',
                    'sample' => '1',
                    'format' => 'json',
                ],JSON_UNESCAPED_UNICODE),
                json_encode(["1","2"]),
                null
            ],
            [2,
                SystemModel::TYPE_MULTIPLE,
                '穿梭框',
                'transfer',
                '穿梭框',
                json_encode([
                    'options' => "1=>选项1\n2=>选项2",
                    'type' => 'transfer',
                    'sample' => '1',
                    'format' => 'json',
                ],JSON_UNESCAPED_UNICODE),
                json_encode(["1","2"]),
                null
            ],
            [2,
                SystemModel::TYPE_SELECT_TREE,
                '树状下拉选择',
                'select_tree',
                '树状下拉选择',
                json_encode([
                    'options' => '[{"value": "11", "label": "北京市", "children": [{"value": "1101", "label": "市辖区", "children": [{"value": "110101", "label": "东城区"}] }] }]',
                    'type' => 'select',
                    'sample' => '1',
                ],JSON_UNESCAPED_UNICODE),
                '110101',
                null
            ],
            [2,
                SystemModel::TYPE_EDITOR,
                '编辑器',
                'editor',
                '编辑器',
                null,
                '1',
                null
            ],
            [2,
                SystemModel::TYPE_DATE,
                '日期选择器',
                'date',
                '日期选择器',
                null,
                date('Y-m-d'),
                null
            ],
            [2,
                SystemModel::TYPE_TIME,
                '时间选择器',
                'time',
                '时间选择器',
                null,
                date('H:i'),
                null
            ],
            [2,
                SystemModel::TYPE_DATETIME,
                '日期时间选择器',
                'datetime',
                '日期时间选择器',
                null,
                date('Y-m-d H:i:s'),
                null
            ],
            [2,
                SystemModel::TYPE_PASSWORD,
                '密码框',
                'password',
                '密码框',
                null,
                '{"decode":"MQ==","encode":"cdd96d3cc73d1dbdaffa03cc6cd7339b"}',
                null
            ],
            [2,
                SystemModel::TYPE_CASCADER,
                '级联选择',
                'cascader',
                '级联选择',
                json_encode([
                    'options' => '[{"value": "11", "label": "北京市", "children": [{"value": "1101", "label": "市辖区", "children": [{"value": "110101", "label": "东城区"}] }] }]',
                    'type' => 'select',
                    'sample' => '1',
                    'format' => 'json',
                ],JSON_UNESCAPED_UNICODE),
                json_encode(["11","1101","110101"]),
                null
            ],
            [2,
                SystemModel::TYPE_OTHER,
                '其他',
                'other',
                null,
                null,
                '1',
                null
            ],
        ];
        
        $configs = $this->combineInserts(
            ['category_id', 'type', 'name', 'slug', 'desc', 'options', 'value', 'validation_rules'],
            $configs,
            [
                'created_at' => now(),
                'updated_at' => now(),
            ]
        );

        DB::table('config_categories')->delete();
        ConfigCategory::insert($categories);

        DB::table('configs')->delete();
        Config::insert($configs);
        $this->info("默认配置创建成功");
    }

    /**
     * 组合字段和对应的值
     *
     * @param array $fields 字段
     * @param array $inserts 值，不带字段的
     * @param array $extra 每列都相同的数据，带字段
     *
     * @return array
     */
    protected function combineInserts(array $fields, array $inserts, array $extra)
    {
        return array_map(function ($i) use ($fields, $extra) {
            $i = array_combine($fields, $i);
            return array_merge($i, $extra);
        }, $inserts);
    }

    /**
     * 创建后台权限
     */
    protected function makeAdminPermission($name, $title)
    {
        $name = underlineToBar(Str::plural($name));
        $pluralKebabDummyResource = Str::kebab($name);
        $adminPermissionList = [
            [
                'name'=>'新增'.$title.'权限',
                'slug'=>'pass-post-'.$name,
                'http_method'=>null,
                'http_path'=>"POST:/{$pluralKebabDummyResource}*\nGET:/{$pluralKebabDummyResource}/create"
            ],
            [
                'name'=>'删除'.$title.'权限',
                'slug'=>'pass-delete-'.$name,
                'http_method'=>'DELETE',
                'http_path'=>'/'.$pluralKebabDummyResource.'*'
            ],
            [
                'name'=>'修改'.$title.'权限',
                'slug'=>'pass-put-'.$name,
                'http_method'=>'PUT',
                'http_path'=>'/'.$pluralKebabDummyResource.'*'
            ],
            [
                'name'=>'查看'.$title.'权限',
                'slug'=>'pass-get-'.$name,
                'http_method'=>'GET',
                'http_path'=>'/'.$pluralKebabDummyResource.'*'
            ],
        ];
        $adminPermission = app(AdminPermission::class);
        foreach ($adminPermissionList as $key => $value) {
            if (!$adminPermission->existAdminPermission($value['slug'])) {
                $adminPermission->create($value);
            } 
        }
    }
}
